local tokens_key = KEYS[1]
local timestamp_key = KEYS[2]
local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])
local fill_time = capacity/rate
local ttl = math.floor(fill_time*2)


-- 获取记录令牌的key
local last_tokens = tonumber(redis.call("get", tokens_key))
if last_tokens == nil then
last_tokens = capacity
end
-- 获取记录时间戳的key
local last_refreshed = tonumber(redis.call("get", timestamp_key))
if last_refreshed == nil then
last_refreshed = 0
end
-- 计算当前访问时间和上一次访问时间差
local delta = math.max(0, now-last_refreshed)
-- 两次访问的时间差加上剩下的令牌数
local filled_tokens = math.min(capacity, last_tokens+(delta*rate))
-- 如果令牌数没有大于requested 那么不允许访问
local allowed = filled_tokens >= requested
local new_tokens = filled_tokens
local allowed_num = 0
-- 如果允许访问那么扣掉这次访问的令牌数 更新当前访问时间
if allowed then
new_tokens = filled_tokens - requested
allowed_num = 1
end
redis.call("setex", tokens_key, ttl, new_tokens)
redis.call("setex", timestamp_key, ttl, now)
return { allowed_num, new_tokens }